/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = jolt_mar.c                                         */
/*  NOTE      =                                                    */
/*  DATE      = 2015/06/03 by songbb                               */
/*******************************************************************/

#include <iconv2utf8.h>

#include "jolt_core.h"
#include "jolt_mar.h"
#include "jolt_comm.h"

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

/**
 * binary类型数据上报长度限制为10M
 */
#define APM_JOLT_BINARY_LIMIT 10485760

union int_float_bits {
    int32_t int_bits;
    float float_bits;
};

union int_double_bits {
    int64_t int_bits;
    double double_bits;
};

/*******************************************************************************
*  FUNC     :  读取stringenc数据
*  ARGS     :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_read_stringenc(L7_jolt_packet *p_st_jolt_packet
                                        , char **pp_out
                                        , unsigned int *p_ui_out_len)
{
    uint8_t uc_i;
    unsigned int ui_len = 0;
    char *p_outtmp = NULL;

    if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i) != FR_SUCC)
        goto error;

    if (uc_i != APM_JOLT_ENCODESTR)
        goto error;

    if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if ((p_outtmp = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
    {
        JOLT_MALLOCK_ERR;
        goto error;
    }

    if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
        goto error;
    *pp_out = p_outtmp;
    *p_ui_out_len = ui_len;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取UTF4数据
*  ARGS     :  *p_st_jolt_sess                           (Jolt私有的session)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_read_UTF4(L7session_jolt *p_st_jolt_sess
                                    , L7_jolt_packet *p_st_jolt_packet
                                    , char **pp_out
                                    , unsigned int *p_ui_out_len)
{
    unsigned int ui_len = 0;
    char *p_outtmp = NULL;
    char *p_arrayOfByte1 = NULL;
    int j = 0;
    int k = APM_JOLT_STRING_BUFSIZ;
    char p_arrayOfByte2[APM_JOLT_STRING_BUFSIZ] = {'\0'};
    int m = 0;
    int n = 0;
    char *p_arrayOfByte3 = NULL;
    int i1 = -1;
    int i2 = 0;
    char *p_arrayOfChar = NULL;
    int i6 = 0;
    int i9 = 0;

    if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    
    if (ui_len == 0)
    {
        *pp_out = NULL;
        *p_ui_out_len = 0;
        return FR_SUCC;
    }

    if (p_st_jolt_sess->i_utf8fix == FR_YES)
    {
        if ((p_arrayOfChar = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
        {
            JOLT_MALLOCK_ERR;
            goto error;
        }
    }
    else
    {
        if ((p_arrayOfByte1 = (char *) frmalloc(2 * ui_len * sizeof(char))) == NULL)
        {
            JOLT_MALLOCK_ERR;
            goto error;
        }
        if ((p_arrayOfByte3 = (char *) frmalloc(4 * sizeof(char))) == NULL)
        {
            JOLT_MALLOCK_ERR;
            goto error;
        }
    }
    while (ui_len > 0)
    {
        int i3;
        if (k >= APM_JOLT_STRING_BUFSIZ)
        {
            if (p_st_jolt_sess->i_utf8fix == FR_YES)
            {
                if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ)) != FR_SUCC)
                    goto error;
                k = 0;
            }
            else
            {
                i3 = 0;
                if (i1 > -1)
                {
                    for (; i3 < i2; i3++)
                    {
                        p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                    }
                }
                if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                    goto error;
                if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                    goto error;
                k = 0;
                i1 = -1;
                i2 = 0;
            }
        }
        int i7 = p_arrayOfByte2[(k++)] & 0xFF;
        int i8;
        switch (i7 >> 4)
        {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                ui_len--;
                if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    p_arrayOfChar[(i6++)] = ((char) i7);
                else
                    p_arrayOfByte1[(j++)] = ((char) i7);
                break;
            case 12:
            case 13:
                if (ui_len - 2 < 0)
                    goto error;
                ui_len--;
                if (k >= APM_JOLT_STRING_BUFSIZ)
                {
                    if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    {
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ)) != FR_SUCC)
                            goto error;
                        k = 0;
                    }
                    else
                    {
                        i3 = 0;
                        if (i1 > -1)
                        {
                            for (; i3 < i2; i3++)
                                p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                        }
                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                            goto error;
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                            goto error;
                        k = 0;
                        i1 = -1;
                        i2 = 0;
                    }
                }
                i8 = p_arrayOfByte2[(k++)] & 0xFF;
                if ((i8 & 0xC0) != 128)
                    goto error;
                ui_len--;
                if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    p_arrayOfChar[(i6++)] = ((char) ((i7 & 0x1F) << 6 | (i8 & 0x3F)));
                else
                {
                    int i10 = ((i7 & 0x1F) << 6 | (i8 & 0x3F)) & 0xFF;
                    if (m == 0)
                    {
                        int i11;
                        switch (i10 >> 4)
                        {
                            case 0:
                            case 1:
                            case 2:
                            case 3:
                            case 4:
                            case 5:
                            case 6:
                            case 7:
                                break;
                            case 12:
                            case 13:
                                if (ui_len - 2 >= 0)
                                {
                                    if (k >= APM_JOLT_STRING_BUFSIZ)
                                    {
                                        i3 = 0;
                                        if (i1 > -1)
                                        {
                                            for (; i3 < i2; i3++)
                                                p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                                        }
                                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                                            goto error;
                                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                                            goto error;
                                        k = 0;
                                        i1 = -1;
                                        i2 = 0;
                                    }
                                    p_arrayOfByte3[0] = p_arrayOfByte2[k];
                                    if ((p_arrayOfByte3[0] & 0x80) != 0)
                                    {
                                        if (k == 255)
                                        {
                                            i1 = 1;
                                            i2 = 1;
                                            unsigned char uc_i = 0;
                                            if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i) != FR_SUCC)
                                                goto error;
                                            p_arrayOfByte3[1] = uc_i;
                                        }
                                        else
                                            p_arrayOfByte3[1] = p_arrayOfByte2[(k + 1)];
                                        i11 = (((p_arrayOfByte3[0] & 0x1F) << 6 | (p_arrayOfByte3[1] & 0x3F)) & 0xFF);
                                        if ((p_st_jolt_sess->i_utf8all == FR_YES) || ((i10 & 0x1C) > 0))
                                            n = 1;
                                        if ((n != 0) && ((p_st_jolt_sess->i_utf8all == FR_YES) || ((i11 & 0xC0) == 128)))
                                            m = 2;
                                        n = 0;
                                    }
                                }
                                break;
                            case 14:
                                if (ui_len - 4 >= 0) {
                                    if (k >= APM_JOLT_STRING_BUFSIZ)
                                    {
                                        i3 = 0;
                                        if (i1 > -1)
                                        {
                                            for (; i3 < i2; i3++)
                                                p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                                        }
                                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                                            goto error;
                                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                                            goto error;
                                        k = 0;
                                        i1 = -1;
                                        i2 = 0;
                                    }
                                    i3 = 0;
                                    int i4 = 0;
                                    for (i4 = k; (i3 < 4) && (i4 < APM_JOLT_STRING_BUFSIZ); i4++)
                                    {
                                        p_arrayOfByte3[i3] = p_arrayOfByte2[i4];
                                        i3++;
                                    }
                                    if (i3 < 4)
                                    {
                                        i4 = i3;
                                        if (i1 > -1)
                                        {
                                            i4 = i3;
                                            int i5;
                                            for (i5 = 0; i5 < i2; i5++)
                                            {
                                                p_arrayOfByte3[i4] = p_arrayOfByte3[(i1 + i5)];
                                                i4++;
                                            }
                                        }
                                        i1 = i3;
                                        i2 = 4 - i3;
                                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i4) != FR_SUCC)
                                            goto error;
                                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte3, (unsigned int) 4 - i4) != FR_SUCC)
                                            goto error;
                                    }
                                    i11 = (((p_arrayOfByte3[0] & 0x1F) << 6 | (p_arrayOfByte3[1] & 0x3F)) & 0xFF);
                                    int i12 = (((p_arrayOfByte3[2] & 0x1F) << 6 | (p_arrayOfByte3[3] & 0x3F)) & 0xFF);
                                    if (((i10 & 0xF) > 0) || ((i11 & 0x3C) > 0))
                                        n = 1;
                                    if ((n != 0) && ((i11 & 0xC0) == 128) && ((i12 & 0xC0) == 128))
                                        m = 3;
                                    n = 0;
                                }
                                break;
                        }
                    }
                    if (m > 0)
                    {
                        p_arrayOfByte1[(j++)] = ((char) i10);
                        m--;
                    }
                    else
                    {
                        p_arrayOfByte1[(j++)] = ((char) i7);
                        p_arrayOfByte1[(j++)] = ((char) i8);
                    }
                }
                break;
            case 14:
                if (ui_len - 3 < 0)
                    goto error;
                ui_len--;
                if (k >= APM_JOLT_STRING_BUFSIZ)
                {
                    if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    {
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ)) != FR_SUCC)
                            goto error;
                        k = 0;
                    }
                    else
                    {
                        i3 = 0;
                        if (i1 > -1)
                        {
                            for (; i3 < i2; i3++)
                                p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                        }
                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                            goto error;
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                            goto error;
                        k = 0;
                        i1 = -1;
                        i2 = 0;
                    }
                }
                i8 = p_arrayOfByte2[(k++)] & 0xFF;
                ui_len--;
                if (k >= APM_JOLT_STRING_BUFSIZ)
                {
                    if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    {
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ)) != FR_SUCC)
                            goto error;
                        k = 0;
                    }
                    else
                    {
                        i3 = 0;
                        if (i1 > -1)
                        {
                            for (; i3 < i2; i3++)
                                p_arrayOfByte2[i3] = p_arrayOfByte3[(i1 + i3)];
                        }
                        if (bytebuff_skip(p_st_jolt_packet->p_st_packet, (size_t) i3) != FR_SUCC)
                            goto error;
                        if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_arrayOfByte2, MIN(ui_len, APM_JOLT_STRING_BUFSIZ) - i3) != FR_SUCC)
                            goto error;
                        k = 0;
                        i1 = -1;
                        i2 = 0;
                    }
                }
                i9 = p_arrayOfByte2[(k++)] & 0xFF;
                if (((i8 & 0xC0) != 128) || ((i9 & 0xC0) != 128))
                    goto error;
                if (p_st_jolt_sess->i_utf8fix == FR_YES)
                    p_arrayOfChar[(i6++)] = ((char) ((i7 & 0xF) << 12 | (i8 & 0x3F) << 6 | (i9 & 0x3F) << 0));
                else
                    p_arrayOfByte1[(j++)] = ((char) ((i7 & 0xF) << 12 | (i8 & 0x3F) << 6 | (i9 & 0x3F) << 0));
                ui_len--;
                break;
            case 8:
            case 9:
            case 10:
            case 11:
            default:
                goto error;
        }
    }
    if (p_st_jolt_sess->i_utf8fix == FR_YES)
    {
        if ((p_outtmp = (char *) frmalloc((i6 + 1) * sizeof(char))) == NULL)
        {
            JOLT_MALLOCK_ERR;
            goto error;
        }
        memcpy(p_outtmp, p_arrayOfChar, (size_t) i6);
        p_outtmp[i6] = '\0';
        *p_ui_out_len = (unsigned int) i6;
    }
    else
    {
        // TODO: return new String(p_arrayOfByte1, 0, j, utf8CharSet);
        if ((p_outtmp = (char *) frmalloc((j + 1) * sizeof(char))) == NULL)
        {
            JOLT_MALLOCK_ERR;
            goto error;
        }
        memcpy(p_outtmp, p_arrayOfByte1, (size_t) j);
        p_outtmp[j] = '\0';
        *p_ui_out_len = (unsigned int) j;
    }

    *pp_out = p_outtmp;

    jolt_free((void **) &p_arrayOfChar);
    jolt_free((void **) &p_arrayOfByte1);
    jolt_free((void **) &p_arrayOfByte3);
    return FR_SUCC;
error:
    jolt_free((void **) &p_arrayOfChar);
    jolt_free((void **) &p_arrayOfByte1);
    jolt_free((void **) &p_arrayOfByte3);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取char数据
*  ARGS     :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_c_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_read_char(L7_jolt_packet *p_st_jolt_packet
                                    , char *p_c_out)
{
    uint8_t uc_i1 = 0;
    uint8_t uc_i2 = 0;
    if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i1) != FR_SUCC)
        goto error;
    if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i2) != FR_SUCC)
        goto error;
    if ((uc_i1 | uc_i2) < 0)
        goto error;

    *p_c_out = (uc_i1 << 8) + (uc_i2 << 0);

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取string数据
*  ARGS     :  *p_st_jolt_sess                           (Jolt私有的session)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_read_string(L7session_jolt *p_st_jolt_sess
                                    , L7_jolt_packet *p_st_jolt_packet
                                    , char **pp_out
                                    , unsigned int *p_ui_out_len)
{
    uint8_t uc_i;
    unsigned int ui_len = 0;
    char c_tmp = 0;

    if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i) != FR_SUCC)
        goto error;

    if (uc_i == APM_JOLT_UTFSTR)
        return __jolt_mar_read_UTF4(p_st_jolt_sess, p_st_jolt_packet, pp_out, p_ui_out_len);

    if (uc_i == APM_JOLT_UNICODESTR)
    {
        if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
            goto error;
        ui_len = ui_len / 2;
        Frstr *p_frstr = NULL;
        if ((p_frstr = frstr_new(ui_len)) == NULL)
            goto error;
        for (; ; )
        {
            ui_len--;
            if (ui_len < 0)
                break;
            if (__jolt_mar_read_char(p_st_jolt_packet, &c_tmp) != FR_SUCC)
                goto error;
            if (frstr_append(p_frstr, &c_tmp, 1) != FR_SUCC)
                goto error;
        }
        *p_ui_out_len = FRSTR_LEN(p_frstr);
        *pp_out = frstr_free2(&p_frstr);
        return FR_SUCC;
    }

error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取mbstring数据
*  ARGS     :  *p_mbencoding                            (MBEncoding编码)
*           :  *p_data                                  (数据入力)
*           :  *ui_data_len                             (数据入力长度)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_get_mbstring(char *p_mbencoding
                                    , char *p_data
                                    , unsigned int ui_data_len
                                    , char **pp_out
                                    , unsigned int *p_ui_out_len)
{
    char *p_buff_out = NULL;

    if (p_mbencoding != NULL)
    {
        if (iconv_to_utf8(p_data, ui_data_len, p_mbencoding, &p_buff_out, p_ui_out_len) == FR_SUCC)
            goto success;
        jolt_free((void **) &p_buff_out);
    }

    if ((p_buff_out = (char *) frmalloc((ui_data_len + 1) * sizeof(char))) == NULL)
    {
        JOLT_MALLOCK_ERR;
        goto error;
    }
    memcpy(p_buff_out, p_data, ui_data_len);
    p_buff_out[ui_data_len] = '\0';
    *p_ui_out_len = ui_data_len;

success:
    *pp_out = p_buff_out;
    return FR_SUCC;
error:
    jolt_free((void **) &p_buff_out);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取mbstring数据
*  ARGS     :  *p_st_jolt_sess                           (Jolt私有的session)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_read_mbstring(L7session_jolt *p_st_jolt_sess
                                    , L7_jolt_packet *p_st_jolt_packet
                                    , char **pp_out
                                    , unsigned int *p_ui_out_len)
{
    uint8_t uc_i;
    unsigned int ui_len = 0;
    char *p_outtmp = NULL;

    if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_i) != FR_SUCC)
        goto error;

    if (uc_i != APM_JOLT_ENCODESTR)
        goto error;

    if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if ((p_outtmp = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
    {
        JOLT_MALLOCK_ERR;
        goto error;
    }
    if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
        goto error;

    if (__jolt_mar_get_mbstring(p_st_jolt_sess->p_mbencoding, p_outtmp, ui_len, pp_out, p_ui_out_len) != FR_SUCC)
        goto error;

    jolt_free((void **) &p_outtmp);
    return FR_SUCC;
error:
    jolt_free((void **) &p_outtmp);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  检测i_jolti18nflag参数
*  ARGS     :  *p_st_jolt_sess                           (Jolt私有的session)
*           :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __jolt_mar_detect_jolti18nflag(L7session_jolt *p_st_jolt_sess
                                            , unsigned int ui_msgparam
                                            , L7_jolt_packet *p_st_jolt_packet)
{
    uint8_t uc_i = 0;

    if (p_st_jolt_sess->i_jolti18nflag != APM_JOLT_FLAG_UNSET)
        return FR_SUCC;
    if (ui_msgparam >> 25 != APM_JOLT_SSTRING)
        return FR_FAIL;

    if (bytebuff_peek_char(p_st_jolt_packet->p_st_packet, &uc_i) != FR_SUCC)
        return FR_FAIL;
    switch (uc_i)
    {
        case APM_JOLT_ENCODESTR:
            p_st_jolt_sess->i_jolti18nflag = FR_YES;
            return FR_SUCC;
        case APM_JOLT_UTFSTR:
        case APM_JOLT_UNICODESTR:
            p_st_jolt_sess->i_jolti18nflag = FR_NO;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取short类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_s_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_short(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , short *p_s_out)
{
    uint16_t s_tmp = 0;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SSHORT:
            if (bytebuff_get_short(p_st_jolt_packet->p_st_packet, 2, &s_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                return FR_FAIL;
            *p_s_out = s_tmp;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取int类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_i_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_int(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , int *p_i_out)
{
    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SSHORT:
            return bytebuff_get_short(p_st_jolt_packet->p_st_packet, 2, (unsigned short *) p_i_out, BYTE_BIG_ENDIAN);
        case APM_JOLT_SINT:
        case APM_JOLT_SSTRUCT: // 自行添加的
            return bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, (unsigned int *) p_i_out, BYTE_BIG_ENDIAN);
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取byte类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_c_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_byte(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , char *p_c_out)
{
    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SBYTE:
            return bytebuff_get_char(p_st_jolt_packet->p_st_packet, (unsigned char *) p_c_out);
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取boolean类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_i_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_boolean(unsigned int ui_msgparam
                        , L7_jolt_packet *p_st_jolt_packet
                        , int *p_i_out)
{
    unsigned char uc_tmp = 0;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SBOOLEAN:
            if (bytebuff_get_char(p_st_jolt_packet->p_st_packet, &uc_tmp) != FR_SUCC)
                return FR_FAIL;
            *p_i_out = uc_tmp != 0 ? FR_YES : FR_NO;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取long类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_ll_out                                (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_long(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , long long *p_ll_out)
{
    uint64_t uint64_tmp = 0LL;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SLONG:
            if (bytebuff_get_long(p_st_jolt_packet->p_st_packet, 8, &uint64_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                return FR_FAIL;
            *p_ll_out = uint64_tmp;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取float类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_f_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_float(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , float *p_f_out)
{
    int i_tmp = 0;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SFLOAT:
            if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, (unsigned int *) &i_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                return FR_FAIL;
            union int_float_bits bits;
            bits.int_bits = i_tmp;
            *p_f_out = bits.float_bits;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取double类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  *p_d_out                                 (数据出力)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_double(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , double *p_d_out)
{
    int i_tmp = 0;
    long long ll_tmp = 0LL;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SFLOAT:
            if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, (unsigned int *) &i_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                return FR_FAIL;
            union int_float_bits float_bits;
            float_bits.int_bits = i_tmp;
            *p_d_out = float_bits.float_bits;
            return FR_SUCC;
        case APM_JOLT_SDOUBLE:
            if (bytebuff_get_long(p_st_jolt_packet->p_st_packet, 8, (uint64_t *) &ll_tmp, BYTE_BIG_ENDIAN) != FR_SUCC)
                return FR_FAIL;
            union int_double_bits double_bits;
            double_bits.int_bits = ll_tmp;
            *p_d_out = double_bits.double_bits;
            return FR_SUCC;
        default:
            return FR_FAIL;
    }
}

/*******************************************************************************
*  FUNC     :  读取string类型数据
*  ARGS     :  *p_st_jolt_sess                           (Jolt私有的session)
*           :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_string(L7session_jolt *p_st_jolt_sess
                    , unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , char **pp_out
                    , unsigned int *p_ui_out_len)
{
    char *p_outtmp = NULL;

    switch (ui_msgparam >> 25)
    {
        case APM_JOLT_SSHORT:
            if ((p_outtmp = (char *) frmalloc(2 * sizeof(char))) == NULL)
            {
                JOLT_MALLOCK_ERR;
                goto error;
            }
            if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, 2) != FR_SUCC)
                goto error;
            *pp_out = p_outtmp;
            *p_ui_out_len = 2;
            break;
        case APM_JOLT_SINT:
            if ((p_outtmp = (char *) frmalloc(4 * sizeof(char))) == NULL)
            {
                JOLT_MALLOCK_ERR;
                goto error;
            }
            if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, 4) != FR_SUCC)
                goto error;
            *pp_out = p_outtmp;
            *p_ui_out_len = 4;
            break;
        case APM_JOLT_SBYTE:
            if ((p_outtmp = (char *) frmalloc(1 * sizeof(char))) == NULL)
            {
                JOLT_MALLOCK_ERR;
                goto error;
            }
            if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, 1) != FR_SUCC)
                goto error;
            *pp_out = p_outtmp;
            *p_ui_out_len = 1;
            break;
        case APM_JOLT_SFLOAT:
            if ((p_outtmp = (char *) frmalloc(4 * sizeof(char))) == NULL)
            {
                JOLT_MALLOCK_ERR;
                goto error;
            }
            if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, 4) != FR_SUCC)
                goto error;
            *pp_out = p_outtmp;
            *p_ui_out_len = 4;
            break;
        case APM_JOLT_SDOUBLE:
            if ((p_outtmp = (char *) frmalloc(8 * sizeof(char))) == NULL)
            {
                JOLT_MALLOCK_ERR;
                goto error;
            }
            if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, 8) != FR_SUCC)
                goto error;
            *pp_out = p_outtmp;
            *p_ui_out_len = 8;
            break;
        case APM_JOLT_SSTRING:
            if (p_st_jolt_sess->i_jolti18nflag == APM_JOLT_FLAG_UNSET && __jolt_mar_detect_jolti18nflag(p_st_jolt_sess, ui_msgparam, p_st_jolt_packet) != FR_SUCC)
                goto error;
            if (p_st_jolt_sess->i_jolti18nflag == FR_YES)
                return __jolt_mar_read_stringenc(p_st_jolt_packet, pp_out, p_ui_out_len);
            else
                return __jolt_mar_read_string(p_st_jolt_sess, p_st_jolt_packet, pp_out, p_ui_out_len);
        case APM_JOLT_SMBSTRING:
            return __jolt_mar_read_mbstring(p_st_jolt_sess, p_st_jolt_packet, pp_out, p_ui_out_len);
        default:
            goto error;
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取binary类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_bytes(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , char **pp_out
                    , unsigned int *p_ui_out_len)
{
    unsigned int ui_len = 0;
    char *p_outtmp = NULL;

    if (ui_msgparam >> 25 != APM_JOLT_SBINARY)
        goto error;

    if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if ((p_outtmp = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
    {
        JOLT_MALLOCK_ERR;
        goto error;
    }

    if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
        goto error;

    *pp_out = p_outtmp;
    *p_ui_out_len = ui_len;

    return FR_SUCC;
error:
    jolt_free((void **) &p_outtmp);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  读取struct类型数据
*  ARGS     :  ui_msgparam                              (MsgParam)
*           :  *p_st_jolt_packet                        (Jolt数据包)
*           :  **pp_out                                 (数据出力)
*           :  *p_ui_out_len                            (数据出力长度)
*  RTN      :  0                                        (FR_SUCC)
*              1                                        (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int jolt_mar_get_struct(unsigned int ui_msgparam
                    , L7_jolt_packet *p_st_jolt_packet
                    , char **pp_out
                    , unsigned int *p_ui_out_len)
{
    unsigned int ui_len = 0;
    char *p_outtmp = NULL;

    if (ui_msgparam >> 25 != APM_JOLT_SSTRUCT)
        goto error;

    if (bytebuff_get_int(p_st_jolt_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;

    if ((p_outtmp = (char *) frmalloc(ui_len * sizeof(char))) == NULL)
    {
        JOLT_MALLOCK_ERR;
        goto error;
    }

    if (bytebuff_get_bytes(p_st_jolt_packet->p_st_packet, p_outtmp, ui_len) != FR_SUCC)
        goto error;

    *pp_out = p_outtmp;
    *p_ui_out_len = ui_len;

    return FR_SUCC;
error:
    jolt_free((void **) &p_outtmp);
    return FR_FAIL;
}
